package hu.mapro.flang.gwt.client.ui.custom;

import java.text.ParseException;

import hu.mapro.flang.gwt.client.request.ApplicationRequestFactory;
import hu.mapro.flang.gwt.domain.client.AutoBeans;
import hu.mapro.flang.gwt.domain.client.AutoBeans.Book;
import hu.mapro.flang.gwt.domain.client.AutoBeans.BookClientStore;
import hu.mapro.flang.gwt.domain.client.AutoBeans.BookFields;
import hu.mapro.flang.gwt.domain.client.AutoBeans.UserPrivilege;
import hu.mapro.gwt.data.client.CachedClientStore;
import hu.mapro.gwt.data.client.CachedClientStoreReader;
import hu.mapro.gwt.data.client.ClientStoreReader;
import hu.mapro.gwtui.gxt.client.data.GxtDataUtils;
import hu.mapro.gwtui.gxt.client.fieldseditor.field.ValueBaseEditorFieldInterface;
import hu.mapro.gwtui.gxt.client.modelkeyprovider.entity.LongIdModelKeyAdapter;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.form.ComboBox;
import com.sencha.gxt.widget.core.client.form.PropertyEditor;




public class CustomCreateFieldVisitor extends AutoBeans.CreateFieldVisitor {

	ApplicationRequestFactory applicationRequestFactory;
	BookClientStore bookClientStore; 
	
	
	@Inject
	public CustomCreateFieldVisitor(
			ApplicationRequestFactory applicationRequestFactory,
			BookClientStore bookClientStore) {
		super();
		this.applicationRequestFactory = applicationRequestFactory;
		this.bookClientStore = bookClientStore;
	}



//	@Override
//	public <O, I extends hu.mapro.model.meta.SingularField<UserPrivilege,O> & hu.mapro.model.Setter<UserPrivilege,O>> hu.mapro.gwtui.gxt.client.fieldseditor.field.EditorFieldInterface<?> setUserPrivilege(I inverseField) {
//		return new UserPrivilegesEditor(inverseField);
//	}
	
	@Override
	public hu.mapro.gwtui.gxt.client.fieldseditor.field.EditorFieldInterface<?> scalarBook() {
		final ListStore<Book> bookFieldStore = new ListStore<Book>(new LongIdModelKeyAdapter());
		ComboBox<Book> field = new ComboBox<Book>(bookFieldStore, GxtDataUtils.labelProvider(BookFields.title));
		field.setTypeAhead(true);
		field.setTriggerAction(TriggerAction.ALL);
		field.setEditable(false);
		
		final PropertyEditor<Book> pe = field.getCell().getPropertyEditor();
		
		field.getCell().setPropertyEditor(new PropertyEditor<AutoBeans.Book>() {
			
			@Override
			public Book parse(CharSequence text) throws ParseException {
				return pe.parse(text);
			}
			
			@Override
			public String render(Book object) {
				return object==null?"":object.getTitle();
			}
		});
		
		// TODO problem with initializing UI before login. UI should only be created after login
		
		final Supplier<Void> nothing = Suppliers.memoize(new Supplier<Void>() {
			@Override
			public Void get() {
				bookClientStore.register(new ClientStoreReader<AutoBeans.Book>() {
					
					@Override
					public void uncached() {
						throw new RuntimeException("unimplemented");
					}
					
					@Override
					public void cached(CachedClientStore<Book> store) {
						store.register(new CachedClientStoreReader<AutoBeans.Book>() {
							@Override
							public void onChange(Iterable<Book> values) {
								bookFieldStore.replaceAll(ImmutableList.copyOf(values));
							}
						}).activate();
					}
				});
				
				return null;
			}
		});
		
		
		return new ValueBaseEditorFieldInterface<Book>(field) {
			
			public <T, A extends hu.mapro.model.Getter<T,Book> & hu.mapro.model.Setter<T,Book>> void edit(A accessor, T baseObject) {
				nothing.get();
				super.edit(accessor, baseObject);
			};
			
			@Override
			protected Book extractValueFromField() {
				return editorField.getValue();
			}
			
			@Override
			public void checkDirty() {
				boolean dirty = false;
				Book value = extractValueFromField();
				if (originalValue==value) {
					dirty = false;
				} else if (originalValue==null || value==null) {
					dirty = true;
				} else {
					dirty = !value.getId().equals(originalValue.getId());
				}
				delegate.setDirty(dirty);
			}
			
//			@Override
//			public void setContext(final FieldCreationInterface ctx) {
//				super.setContext(ctx);
//				
//				// TODO maybe list only when requested
//				ctx.addNewSessionHandler(new Callback<RequestContext>() {
//
//					@Override
//					public void onResponse(RequestContext value) {
//						BookRequestContext rc = value.append(applicationRequestFactory.book());
//						FactoryInit f = JpaDomain.factory(rc);
//						ListConfig listConfig = f.listConfig();
//						SortingConfig sortingConfig = f.sortingConfig();
//						FieldProperty fieldProperty = f.fieldProperty();
//						fieldProperty.setFieldName(BookFields.title.getName());
//						sortingConfig.setPath(fieldProperty);
//						sortingConfig.setDirection(SortingDirection.ASCENDING);
//						listConfig.getSortingConfigs().add(sortingConfig);
//						rc.list(listConfig).to(new Receiver<List<Book>>() {
//							@Override
//							public void onSuccess(List<Book> response) {
//								bookFieldStore.replaceAll(response);
//							}
//						});
//					}
//				});
//				
//			}
		};
	}
	
}
